<?php

/* Plugins.php
 *
 * (C) 2012, StaySimple CMS team.
 *
 * This file is part of StaySimple.
 * http://code.google.com/p/stay-simple-cms/
 *
 * StaySimple is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * StaySimple is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with StaySimple.  If not, see <http://www.gnu.org/licenses/>.
 */

class Plugins extends Administration {

    private $exclude = array('.', '..', '.git', '.svn');

    public function __construct() {
        parent::__construct();
        $this->validateUser();
    }

    /**
     * Searches the plugin directory for installed plugins. As far as this 
     * method is concerned, all folders inside the plugin folder will be plugins.
     * 
     * @return string[]
     */
    private function findAllInstalledPlugins() {
        $plugins = array();

        if (($dh = opendir(PLUGINROOT))) {
            while (($filename = readdir($dh)) !== false) {
                if (is_dir(PLUGINROOT . '/' . $filename) && !in_array($filename, $this->exclude)) {
                    $plugins [] = basename($filename);
                }
            }
            closedir($dh);
        }

        return $plugins;
    }

    public function start($params = array()) {
        $plugins = $this->findAllInstalledPlugins();

        $filterOptions = array(
            array('0', $this->t('STAY_PLUGINS_FILTER_ALL')),
            array('1', $this->t('STAY_PLUGINS_FILTER_ACTIVE')),
            array('2', $this->t('STAY_PLUGINS_FILTER_INACTIVE')),
        );

        $filter = 0;
        if (isset($_POST['filter'])) {
            $filter = intval($_POST['filter']);
        }

        $this->render('list.plugins', array(
            'plugins' => $plugins,
            'active' => 'plugins',
            'filterOptions' => $filterOptions,
            'filter' => $filter
        ));
    }

    public function disable($params = array()) {
        if (isset($params[0]) && Plugin::isActive($params[0])) {
            $this->deactivatePlugin($params[0]);
            $this->queueMessage(new Message($this->t('STAY_PLUGINS_PLUGIN_DEACTIVATED', array($plugin))));
        }
        $this->redirect('plugins');
    }

    public function enable($params = array()) {
        if (isset($params[0]) && $params[0] && !Plugin::isActive($params[0])) {
            $plugin = $params[0];
            Plugin::activate(new $params[0]());
            StaySimpleCMS::app()->savePluginConfig();
            $this->queueMessage(new Message($this->t('STAY_PLUGINS_PLUGIN_ACTIVATED', array($plugin))));
            echo('success');
        }
    }

    public function activationError($params = array()) {
        if (isset($params[0])) {
            $plugin = $params[0];
            $this->queueMessage(new Message($this->t('STAY_PLUGINS_PLUGIN_ACTIVATION_ERROR', array($plugin))));
        }
        $this->redirect('plugins');
    }

    public function install($params = array()) {
        foreach ($_FILES as $file) {
            $file = (object) $file;
            if (!$file->error) {
                $zip = zip_open($file->tmp_name);
                if ($zip) {
                    while ($entry = zip_read($zip)) {
                        $filename = PLUGINROOT . '/' . zip_entry_name($entry);
                        if (!is_dir(dirname($filename)))
                            mkdir(dirname($filename), 0777, true);

                        if (zip_entry_filesize($entry)) {
                            file_put_contents($filename, zip_entry_read($entry, zip_entry_filesize($entry)));
                        }
                    }

                    $this->queueMessage(new Message($this->t('STAY_PLUGINS_PLUGIN_INSTALL_SUCCESS'), Message::$SUCESS));
                    recreateAutoloadCache();
                } else {
                    $this->queueMessage(new Message($this->t('STAY_PLUGINS_INVALID_FILETYPE'), Message::$ERROR));
                }
            } else {
                $this->queueMessage(new Message($this->t('STAY_PLUGINS_UPLOAD_ERROR'), Message::$ERROR));
            }
        }
        $this->redirect('plugins');
    }

    public function uninstall($params = array()) {
        if (isset($params[0]) && $params[0]) {
            if ($this->uninstallPlugin($params[0])) {
                $this->queueMessage(new Message($this->t('STAY_PLUGINS_PLUGIN_UNINSTALED')));
            } else {
                $this->queueMessage(new Message($this->t('STAY_PLUGINS_PLUGIN_UNINSTALATION_ERROR'), Message::$ERROR));
            }
        }
        $this->redirect('plugins');
    }

    /**
     * Delete folder function. Just delegates to <em>File</em> static methods.
     * 
     * @return boolean
     * 
     * @see File::deleteFileAndDirectory()
     */
    private function deleteDirectory($dir) {
        return File::deleteFileAndDirectory($dir);
    }

    public function changeSelected($params = array()) {
        if (isset($_POST['selected'])) {
            if (isset($_POST['action'])) {
                $selected = $_POST['selected'];
                $max = count($selected);
                $count = 0;

                switch ($_POST['action']) {
                    case 'activate':
                        foreach ($selected as $plugin) {
                            if (!Plugin::isActive($plugin)) {
                                Plugin::activate(new $plugin());
                                StaySimpleCMS::app()->savePluginConfig();
                            }
                        }
                        $this->queueMessage(new Message($this->t('STAY_PLUGINS_SELECTED_PLUGINS_ACTIVATED', array($plugin))));
                        echo('success');
                        break;
                    case 'deactivate':
                        foreach ($selected as $plugin) {
                            $this->deactivatePlugin($plugin);
                            $this->queueMessage(new Message($this->t('STAY_PLUGINS_PLUGIN_DEACTIVATED', array($plugin))));
                        }
                        break;
                    case 'uninstall':
                        foreach ($selected as $plugin) {
                            if ($this->uninstallPlugin($plugin)) {
                                $count++;
                            }
                        }

                        if ($count == 0) {
                            $this->queueMessage(new Message('STAY_PLUGINS_SELECTED_UNINSTALL_ALL_ERROR', Message::$ERROR));
                        } else if ($count != $max) {
                            $this->queueMessage(new Message('STAY_PLUGINS_SELECTED_UNINSTALL_SOME_ERROR', Message::$ERROR));
                        } else {
                            $this->queueMessage(new Message('STAY_PLUGINS_SELECTED_UNINSTALL_SUCCESS'));
                        }
                        break;
                    default:
                        $this->queueMessage(new Message('STAY_GENERAL_INVALID_REQUEST', Message::$ERROR));
                }
            } else {
                $this->queueMessage(new Message('STAY_GENERAL_INVALID_REQUEST', Message::$ERROR));
            }
        }

        $this->redirect('plugins');
    }

    private function uninstallPlugin($plugin) {
        $success = true;

        if (Plugin::isActive($plugin))
            Plugin::deactivate($plugin);

        $success = $this->deleteDirectory(PLUGINROOT . '/' . $plugin);

        StaySimpleCMS::app()->savePluginConfig();

        return $success;
    }

    private function deactivatePlugin($plugin) {
        Plugin::deactivate($plugin);
        StaySimpleCMS::app()->savePluginConfig();
    }

}